Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make First Ingredient never able to be deleted

I'm making an ingredients application where users insert ingredients

My application looks like this:enter image description here

As you can see, the first ingredients span doesn't have a X at the end, because you must have at least one ingredient, but the rest of the ingredient spans do. I'm also using the Jquery Sortable Plugin so if you click near the outside of any of the ingredient spans, you can change the order of the ingredients. This works fine, except if you move the first ingredient span, then that span doesn't have an X at the end, even if you move it to the last spot.

So what I'm trying to do is make the first ingredient span always have no X at the end, even if switched order with another ingredient span. I tried this:

$('ingredientsCOUNT > span:first').hide(deleteButton);

but it didn't work? Any other suggestions? All help is greatly appreciated, and here's my code:

HTML (the php can just be ignored!)

<div class='formelementcontainer funky'>
        <label for="ingredient">Ingredients</label>
        <div id='ingredientsCOUNT' class='sortable'>
            <span>
                <input type="text" class='small' name="ingredient" id="ingredient" placeholder='QTY'/>
                <select name='measurements'>
                    <option value='' name='' checked='checked'>--</option>
                    <?foreach ($measurements as $m):?>
                        <option value='<?=$m->id;?>'><?=$m->measurement;?></option>
                    <?endforeach;?>
                </select>
                <input type="text" name="ingredient" id="ingredient" placeholder='Ingredient'/>
            </span>
        </div>
        <div class="clear"></div>
        <div class='addSPAN tabover'>
            <a class='float-right' id='btnAddIngredients' href='#'>Add Ingredient</a>
        </div>
</div>

jQuery

(function($) { 
$(document).ready(function () {
    $('#btnAddIngredients').click(function () {
        var num = $('#ingredientsCOUNT span').length;
        var newNum = new Number(num + 1);
        var deleteButton = $("<a class='float-right' style='margin:10px 2px;' href='#'><img src='<? echo base_url()."public/img/delete.png";?>' height='11' width='11' /></a>");
        deleteButton.click(deleteThis);
        $('#ingredientsCOUNT > span:first')
            .clone()
            .attr('name', 'ingredient' + newNum)
            .append(deleteButton)
            .appendTo('#ingredientsCOUNT')
            .fadeIn();
        $('ingredientsCOUNT > span:first').hide(deleteButton); //THIS IS MY SOLUTION THAT DIDN'T WORK
    });
    function deleteThis() {
        var span = $(this).closest('span')
        span.fadeOut('slow', function() { span.remove(); });
    }
    $( ".sortable" ).sortable();       //jQuery Sortable initialized
});

})(jQuery);
like image 214
Muhambi Avatar asked Mar 25 '13 21:03

Muhambi


2 Answers

How about hiding it with CSS? The following assumes you added a class delete-button to your delete links:

#ingredientsCOUNT > span:first-child .delete-button { display: none; }

With that CSS, you can reorder the list, add or remove items, and the first delete button will never show.

like image 141
bfavaretto Avatar answered Oct 22 '22 18:10

bfavaretto


Since :first-child is quirky in oldIE ( https://developer.mozilla.org/en-US/docs/CSS/:first-child#Internet_Explorer_notes ), it's possible to use the Sortable API like this:

$(".sortable").sortable({
    update: function (event, ui) {
        var rows = $("#ingredientsCOUNT").children("span");
        rows.removeClass("first-child");
        rows.first().addClass("first-child");
    }
});

(there's probably a better way to utilize the event and/or ui parameters)

This way, you wouldn't have to determine which row to add a delete button to; you would always include a delete button in every row in your HTML. Then, when a sorting is done, the jQuery in the stop event (EDIT: update event) will hide the first row's delete button and show the rest (via classes).

Of course, you would need this CSS:

#ingredientsCOUNT > span.first-child a.delete-button {
    display: none;
}

And to add a delete-button class to your delete buttons <a>

EDIT:

I changed the Sortable method from stop to update so that it only runs the code when the sorting arrangement has actually changed, after the sorting is done.

like image 2
Ian Avatar answered Oct 22 '22 18:10

Ian